package metrics

import (
	"context"
	"fmt"
	"net/http"
	"sync"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"go.uber.org/zap"
)

// Server represents the metrics server
type Server struct {
	registry *prometheus.Registry
	server   *http.Server
	logger   *zap.Logger
	mu       sync.Mutex
}

// NewServer creates a new metrics server
func NewServer(port int, path string, logger *zap.Logger) *Server {
	registry := prometheus.NewRegistry()
	
	mux := http.NewServeMux()
	mux.Handle(path, promhttp.HandlerFor(registry, promhttp.HandlerOpts{
		Registry: registry,
	}))

	return &Server{
		registry: registry,
		server: &http.Server{
			Addr:    fmt.Sprintf(":%d", port),
			Handler: mux,
		},
		logger: logger,
	}
}

// Start starts the metrics server
func (s *Server) Start() error {
	s.logger.Info("Starting metrics server",
		zap.String("address", s.server.Addr),
	)
	
	if err := s.server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
		return fmt.Errorf("metrics server error: %v", err)
	}
	
	return nil
}

// Stop stops the metrics server
func (s *Server) Stop(ctx context.Context) error {
	s.logger.Info("Stopping metrics server")
	return s.server.Shutdown(ctx)
}

// RegisterCollector registers a new prometheus collector
func (s *Server) RegisterCollector(collector prometheus.Collector) error {
	s.mu.Lock()
	defer s.mu.Unlock()

	if err := s.registry.Register(collector); err != nil {
		return fmt.Errorf("failed to register collector: %v", err)
	}
	return nil
}

// UnregisterCollector unregisters a prometheus collector
func (s *Server) UnregisterCollector(collector prometheus.Collector) bool {
	s.mu.Lock()
	defer s.mu.Unlock()

	return s.registry.Unregister(collector)
} 